package com.baizhi.shane.shane.service.impl;

import com.baizhi.shane.common.base.Result;
import com.baizhi.shane.constant.SysMapping;
import com.baizhi.shane.enums.ResultCode;
import com.baizhi.shane.shane.dto.LabelListByContentOutDTO;
import com.baizhi.shane.shane.entity.ShaneQuestionLabelRel;
import com.baizhi.shane.shane.service.ShaneQuestionLabelRelService;
import com.baizhi.shane.shane.vo.*;
import com.baizhi.shane.sys.utils.CommonUtils;
import com.baizhi.shane.sys.vo.IdVO;
import com.baizhi.shane.sys.vo.SuccessedOutVO;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baizhi.shane.shane.entity.ShaneLabel;
import com.baizhi.shane.shane.service.ShaneLabelService;
import com.baizhi.shane.shane.mapper.ShaneLabelMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.core.io.ResourceLoader;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
* @author wbz12
* @description 针对表【shane_label(啥呢标签表)】的数据库操作Service实现
* @createDate 2023-07-25 22:33:37
*/
@Service
@Slf4j
public class ShaneLabelServiceImpl extends ServiceImpl<ShaneLabelMapper, ShaneLabel>
    implements ShaneLabelService{
    @Resource
    private CommonUtils commonUtils;
    @Resource
    private ResourceLoader resourceLoader;
    @Resource
    private ShaneLabelMapper shaneLabelMapper;
    @Resource
    private ShaneQuestionLabelRelService shaneQuestionLabelRelService;

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public OperOutVO insertOne(LabelInsertInVO labelInsertInVO) {
        if (labelInsertInVO == null) {
            Result.fail(ResultCode.PARAM_IS_INVALID);
        }

        ShaneLabel shaneLabel = new ShaneLabel();
        BeanUtils.copyProperties(labelInsertInVO,shaneLabel);

        boolean success = this.save(shaneLabel);
        OperOutVO operOutVO = new OperOutVO();
        operOutVO.setInfoStr(commonUtils.boolToString(success));

        return operOutVO;
    }

    @Override
    public OperOutVO initLevelOne() {
        org.springframework.core.io.Resource resource = resourceLoader.getResource("classpath:nothing/处理知乎一级标签.txt");
        String fileText = "";

        try (InputStream inputStream = resource.getInputStream()) {
            fileText = IOUtils.toString(inputStream, StandardCharsets.UTF_8);
        } catch (IOException e) {

        }

        String[] textSplit = fileText.split("\n");
        List<String> labelList = new ArrayList<>(Arrays.asList(textSplit));
        labelList.remove(0);
        for (int i = 0; i < labelList.size(); i++) {
            String label = labelList.get(i);
            label = label.replaceAll("\r", "");
            labelList.set(i, label);
        }
        log.info(labelList.toString());

        for (String label : labelList) {
            String[] labelArray = label.split(" ");
            ShaneLabel shaneLabel = new ShaneLabel();
            shaneLabel.setZhihuDataId(labelArray[0]);
            shaneLabel.setLevel(1);
            shaneLabel.setContent(labelArray[1]);
            this.save(shaneLabel);
        }
        OperOutVO operOutVO = new OperOutVO();
        operOutVO.setInfoStr(SysMapping.SUCCESS_STRING);

        return operOutVO;
    }

    @Override
    public List<LabelListByContentOutVO> listByContent(LabelListByContentInVO labelListByContentInVO) {
        String query = labelListByContentInVO.getQuery();
        List<LabelListByContentOutDTO> labelListByContentOutDTOList = shaneLabelMapper.listByContent(query);
        List<LabelListByContentOutVO> resultList = new ArrayList<>();
        for (LabelListByContentOutDTO labelListByContentOutDTO : labelListByContentOutDTOList) {
            LabelListByContentOutVO labelListByContentOutVO = new LabelListByContentOutVO();
            BeanUtils.copyProperties(labelListByContentOutDTO,labelListByContentOutVO);
            labelListByContentOutVO.setQuery(query);
            resultList.add(labelListByContentOutVO);
        }

        return resultList;
    }

    /**
     * 通过问题标签关系表的ID解除指定问题和标签的关联
     *
     * @Author 闻柏智
     * @Date 17:45 2024/1/15
     * @Param idVO
     * @return com.baizhi.shane.sys.vo.SuccessedOutVO
     **/
    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public SuccessedOutVO deleteOneLabelQuestionRel(IdVO idVO) {
        Long relId = idVO.getId();
        boolean successed = shaneQuestionLabelRelService.removeById(relId);
        SuccessedOutVO successedOutVO =
                commonUtils.boolToSuccessedOutVO(successed, SysMapping.DELETE_REL_SUCCESS, SysMapping.DELETE_REL_FAIL);
        return successedOutVO;
    }

    /**
     * 树形查询所有标签
     *
     * @Author 闻柏智
     * @Date 18:43 2024/1/15
     * @Param
     * @return java.util.List<com.baizhi.shane.shane.vo.TreeLabelVO>
     **/
    @Override
    public List<TreeLabelVO> treeListAllLabel() {
        // 查询所有标签
        List<ShaneLabel> shaneLabelList = this.list();
        // 提取所有一级标签
        List<ShaneLabel> oneLevelList = shaneLabelList
                .stream()
                .filter(shaneLabel -> shaneLabel.getLevel().equals(1))
                .collect(Collectors.toList());
        /* 初始化返回值列表 */
        List<TreeLabelVO> treeLabelVOList = new ArrayList<>();
        /* 将所有一级标签放入返回值列表中 */
        for (ShaneLabel shaneLabel : oneLevelList) {
            TreeLabelVO treeLabelVO = new TreeLabelVO();
            treeLabelVO.setChildren(new ArrayList<>());
            BeanUtils.copyProperties(shaneLabel, treeLabelVO);
            treeLabelVOList.add(treeLabelVO);
        }
        /* 提取所有二级标签 */
        List<ShaneLabel> twoLevelList = shaneLabelList
                .stream()
                .filter(shaneLabel -> shaneLabel.getLevel().equals(2))
                .collect(Collectors.toList());
        /* 二级标签列表按照父级ID分组 */
        Map<Long, List<ShaneLabel>> twoLevelMap = twoLevelList
                .stream()
                .collect(Collectors.groupingBy(ShaneLabel::getParentId));
        /* 遍历返回值列表，将二级标签的数据作为子节点匹配岛一级标签中 */
        for (TreeLabelVO treeLabelVO : treeLabelVOList) {
            // 获取一级标签
            Long oneLevelId = treeLabelVO.getId();
            /* 如果该一级标签下面没有二级标签，就直接跳过 */
            if (!twoLevelMap.containsKey(oneLevelId)) {
                continue;
            }
            // 提取当前一级标签下属的所有二级标签列表
            List<ShaneLabel> twoLabelListNow = twoLevelMap.get(oneLevelId);
            List<TreeLabelVO> twoLabelTree = this.labelToTreeVO(twoLabelListNow);
            treeLabelVO.setChildren(twoLabelTree);
        }

        return treeLabelVOList;
    }

    /**
     * 通过问题ID和标签ID关联问题和标签
     *
     * @Author 闻柏智
     * @Date 19:06 2024/1/15
     * @Param labelIdAndEntityIdVO
     * @return com.baizhi.shane.sys.vo.SuccessedOutVO
     **/
    @Override
    public SuccessedOutVO insertOneQuestionLabelRel(LabelIdAndEntityIdVO labelIdAndEntityIdVO) {
        Long labelId = labelIdAndEntityIdVO.getLabelId();
        Long entityId = labelIdAndEntityIdVO.getEntityId();
        ShaneQuestionLabelRel shaneQuestionLabelRel = new ShaneQuestionLabelRel();
        shaneQuestionLabelRel.setQuestionId(entityId);
        shaneQuestionLabelRel.setLabelId(labelId);
        boolean successed = this.shaneQuestionLabelRelService.save(shaneQuestionLabelRel);
        SuccessedOutVO successedOutVO = commonUtils.boolToSuccessedOutVO(successed, SysMapping.INSERT_REL_SUCCESS, SysMapping.INSERT_REL_FAIL);
        return successedOutVO;
    }

    /**
     * 将输入的ShaneLabel列表转为TreeLabelVO列表
     *
     * @Author 闻柏智
     * @Date 18:39 2024/1/15
     * @Param shaneLabelList
     * @return java.util.List<com.baizhi.shane.shane.vo.TreeLabelVO>
     **/
    private List<TreeLabelVO> labelToTreeVO(List<ShaneLabel> shaneLabelList) {
        // 初始化VO列表
        List<TreeLabelVO> treeLabelVOList = new ArrayList<>();
        /* 遍历，转换类型 */
        for (ShaneLabel shaneLabel : shaneLabelList) {
            TreeLabelVO treeLabelVO = new TreeLabelVO();
            BeanUtils.copyProperties(shaneLabel, treeLabelVO);
            treeLabelVOList.add(treeLabelVO);
        }
        return treeLabelVOList;

    }
}




